package business.player.Robot;

import BaseCommon.CommLog;
import business.global.GM.MaintainGameMgr;
import business.global.club.Club;
import business.global.club.ClubMember;
import business.global.club.ClubMgr;
import business.global.config.GameListConfigMgr;
import business.global.room.base.AbsRoomPos;
import business.global.room.base.RobotRoom;
import business.global.room.key.RoomKeyMgr;
import business.global.shareclub.ShareClubMemberMgr;
import business.global.sharegm.ShareNodeServerMgr;
import business.global.shareroom.ShareRoom;
import business.global.shareroom.ShareRoomMgr;
import business.global.shareroom.ShareRoomPosInfoShort;
import business.global.shareunion.ShareUnionListMgr;
import business.global.union.Union;
import business.global.union.UnionMgr;
import business.player.Player;
import business.player.PlayerMgr;
import business.rocketmq.bo.MqAbsRequestBo;
import business.rocketmq.constant.MqTopic;
import business.shareplayer.ShareNode;
import business.shareplayer.SharePlayerMgr;
import cenum.RoomTypeEnum;
import com.ddm.server.common.CommLogD;
import com.ddm.server.common.Config;
import com.ddm.server.common.rocketmq.MqProducerMgr;
import com.ddm.server.common.task.ScheduledExecutorServiceMgr;
import com.ddm.server.common.utils.Lists;
import com.ddm.server.websocket.def.ErrorCode;
import com.google.gson.Gson;
import core.config.server.GameTypeMgr;
import core.db.entity.clarkGame.UnionRoomConfigBO;
import core.db.other.Restrictions;
import core.db.service.clarkGame.UnionRoomConfigBOService;
import core.ioc.ContainerMgr;
import core.network.http.proto.SData_Result;
import jsproto.c2s.cclass.GameType;
import jsproto.c2s.cclass.GameTypeUrl;
import jsproto.c2s.cclass.club.Club_define;
import jsproto.c2s.cclass.room.BaseRoomConfigure;
import jsproto.c2s.cclass.room.RobotRoomConfig2;
import jsproto.c2s.cclass.room.RoomPosInfoShort;
import jsproto.c2s.iclass.club.CClub_Join;
import jsproto.c2s.iclass.club.CClub_SportsPointUpdate;
import jsproto.c2s.iclass.room.CBase_EnterRoom;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class RobotMgr3 {

    private static RobotMgr3 instance = new RobotMgr3();

    LinkedList<Player> availableClubList;
    LinkedList<Player> usedClubList = new LinkedList<>();
    Map<Long,Player> usedIds = new HashMap<>();
    Set<Long> allIds;


    int min_entertime = 1;
    int max_entertime = 50;
    int mintime = 0;
    int maxtime = 3;

    //获取所有俱乐部里面带机器人的 UnionRoomConfigBO，每次都重新获取，与现有的进行比较，如果有增加则立即增加，减少或者删除的等到解散之后就不自动创建新的了。
    //机器人列表用队列维护，一个在玩的列表，一个空闲的列表，玩完的或者新玩的自动从一个队列加入到另外一个队列，同时维护ShareRoomMgr

    public final int limitID = 69000000;
    public  int times = 0;

    public static RobotMgr3 getInstance() {
        return instance;
    }

    public void init() {
        if(true){
//            return;
        }
        ///loadRobots("robots.txt");
        final Random random = new Random();
        ScheduledExecutorServiceMgr.getInstance().getScheduledFuture(() -> {

//            ClubMember opClubMember = ClubMgr.getInstance().getClubMemberMgr().find(req.getOpPid(), req.getClubId(), Club_define.Club_Player_Status.PLAYER_JIARU);
//            opClubMember.getClubMemberBO().getSportsPoint()
//            final CClub_SportsPointUpdate req = new Gson().fromJson(message, CClub_SportsPointUpdate.class);//上下分
//            SData_Result result = ClubMgr.getInstance().getClubMemberMgr().execSportsPointUpdate(req,player.getPid(),player);
//            this.getClubMemberMgr().onInsertClubMember(player, club, Club_define.Club_MINISTER.Club_MINISTER_GENERAL.value(), club.clubListBO.getOwnerID())
//            ClubMgr.getInstance().onJoinClub(player, req);  CClubJoin
            // 检查加入
//            result = UnionMgr.getInstance().getUnionMemberMgr().checkJoinUnion((Union) room.getRoomTyepImpl().getSpecialRoom(), clubId, this.player, room.getRoomPidAll(), room.getBaseRoomConfigure().getBaseCreateRoom());
//            getUnionBO().getClubId() 根据clubid和playerid判断是否属于这个朋友圈   朋友圈添加机器人，初始化积分
//            player增加clubid对应已经分配到哪个俱乐部，isandroid=2是陪玩机器人，1是暖场机器人
//            加入房间需要判断入场分，对于低于入场分的需要给上分，对于赢的分数，如果太多也可以下分
//            UnionMgr.getInstance().getUnionMemberMgr().checkJoinUnion入场分检查  PlayerUnionRoom？？？

            try {
                times++;
                if(availableClubList==null){
                    availableClubList = Lists.newLinkedList(PlayerMgr.getInstance().getAllClubRobotPlayers());
                    allIds = new HashSet<>();
                    for (Player player:availableClubList
                         ) {
                        player.getPlayerBO().saveAndroid(player.getPlayerBO().getAndroid());
                        allIds.add(player.getPid());
                    }
                }
                Map<Long, Union> map = ShareUnionListMgr.getInstance().getAllUnion();
                Collection<Union> unionSet = ShareUnionListMgr.getInstance().getAllUnion().values();
//                Collection<Union> unionSet = UnionMgr.getInstance().getUnionListMgr().getUnionMap().values();
//                Collection<Club> clubSet = ClubMgr.getInstance().getClubListMgr().getClubMap().values();
                for (Map.Entry<Long,Union> entry: map.entrySet()) {
                    Union union = entry.getValue();
//                    if (entry.getKey()==101233){
//                        System.out.println(22);
//                        System.out.println(union.getUnionBO().getRobotNum());
//                    }
                    if(union.getUnionBO().getRobotNum()>0){
                        long clubId = union.getUnionBO().getClubId();
                        List<Player> players = PlayerMgr.getInstance().getAllClubRobotPlayers();
                        long num = players.stream().filter(p -> p.getPlayerBO().getClubId()==clubId).count();
                        if(num<union.getUnionBO().getRobotNum()){
                            addPlayers2ClubUnion(union.getUnionBO().getRobotNum() - num,union,union.getUnionBO().getRobotInitScore());
                        }

                        List<ShareRoom> roomList = ShareRoomMgr.getInstance().roomUnionValues(RoomTypeEnum.UNION, union.getUnionBO().getId(), new ArrayList<>() , 0, 0,0);

                        Set<Long> playingIds = new HashSet<>();
                        Set<Long> newIds = new HashSet<>();
                        for (ShareRoom room : roomList) {
                            if (null == room) {
                                continue;
                            }
                            if(times%5 == 0){
                                List<ShareRoomPosInfoShort> posList = room.getPosList();
                                for (ShareRoomPosInfoShort pos:posList
                                     ) {
                                    if(allIds.contains(pos.getPid())){
                                        playingIds.add(pos.getPid());
                                    }
                                }
                            }
                            CommLog.debug("[RobotMgr] room: {}  {}", clubId,room.getRoomKey());
                            // 房间里面的空位
                            int emptyPosSize = room.getEmptyPosCount();
                            int fullPosSize = room.getPosList().size();
//                            头像处理应该模拟之前的服务器做个中转，否则每个游戏都需要处理头像显示问题
                            if (0 < emptyPosSize&&emptyPosSize<fullPosSize) {//坐人的桌子，没坐人的先不处理，如果满人的触发机器人点准备，检查机器人数量和进入时间间隔
//                                int androidPosSize = (int) room.getPosList().stream().filter((x) -> x.getPlayer()!=null&&x.getPlayer().getAndroid() == 1).count();

                                int min_entercnt = 1;
                                int max_entercnt = fullPosSize - 1;
                                int s = random.nextInt(max_entercnt) % (max_entercnt - min_entercnt + 1) + min_entercnt;
                                s = s < emptyPosSize ? s : emptyPosSize;
                                for (int i = 0; i < s; i++) {
                                    for (int j = 0; j < availableClubList.size(); j++) {
                                        Player rber = availableClubList.get(j);
                                        if (null != rber && rber.getPlayerBO().getClubId()==room.getBaseRoomConfigure().getBaseCreateRoom().getClubId()) {

                                            boolean enter = enterRoom(rber,clubId,room.getRoomKey());

                                            CommLog.debug("[RobotMgr] enterRoom:{}  {}  {}",rber.getPid(), clubId,room.getRoomKey());
                                            //boolean enter = rber.onEnterRoom(room.getRoomId());
//                                        SData_Result enterResult = UnionRoomMgr.getInstance().findAndEnter(room, rber.getPid(), true);
                                            if(enter){
                                                availableClubList.remove(j);
                                                usedClubList.add(rber);//结束之后需要从列表里面拿出来
                                                usedIds.put(rber.getPid(),rber);
                                                newIds.add(rber.getPid());
                                                return;
                                            }else{
                                                //availableClubList.add(rber);
                                            }
//                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if(times%5 == 0){
                            List<Long> tempList = new ArrayList<>();
//                            List<Player> tempList2 = new ArrayList<>();
                            for (Long usedId : usedIds.keySet()) {
                                if(!newIds.contains(usedId) && !playingIds.contains(usedId)){
                                    tempList.add(usedId);
                                    availableClubList.add(usedIds.get(usedId));
                                    usedIds.get(usedId).getRoomInfo().setRoomId(0);
                                }
                            }
                            for (Long usedId : tempList) {
                                usedIds.remove(usedId);
                            }
                        }
                    }
                }

            } catch (Exception e) {
                CommLog.error("[RobotMgr] error:{}",e.getMessage(), e);
            }
//
//            try {
//                List<AbsBaseRoom> querys = UnionRoomMgr.getInstance().queryExistEmptyPos();
//                if (null != querys) {
//                    for (AbsBaseRoom room : querys) {
//                        if (null == room) {
//                            continue;
//                        }
//                        // 房间里面的空位
//                        int emptyPosSize = room.getRoomPosMgr().getEmptyPosCount();
//                        int fullPosSize = room.getRoomPosMgr().getFullPosCount();
//                        if (0 < emptyPosSize) {
//                            int androidPosSize = (int) room.getRoomPosMgr().getPosList().stream().filter((x) -> x.getPlayer()!=null&&x.getPlayer().getAndroid() == 1).count();
//
//                            int min_entercnt = 1;
//                            int max_entercnt = fullPosSize - 1;
//                            int s = random.nextInt(max_entercnt) % (max_entercnt - min_entercnt + 1) + min_entercnt;
//                            s = s < emptyPosSize ? s : emptyPosSize;
//                            for (int i = 0; i < s; i++) {
//                                Player rber = availableClubList.pop();
//                                if (null != rber && rber.getPlayerBO().getClubId()==room.getBaseRoomConfigure().getBaseCreateRoom().getClubId()) {
//                                    SData_Result enterResult = UnionRoomMgr.getInstance().findAndEnter(room, rber.getPid(), true);
//                                    if(enterResult.getCode()== ErrorCode.Success){
//                                        usedClubList.add(rber);//结束之后需要从列表里面拿出来
//                                    }else{
//                                        availableClubList.add(rber);
//                                    }
//                                    break;
//                                }
//                            }
//                        }
//                    }
//                }
//            } catch (Exception e) {
//                CommLog.error("[RobotMgr] error:{}",e.getMessage(), e);
//            }


        }, 60000, 10000);
    }

    private boolean enterRoom(Player player, long clubId, String roomId) {
        if(Config.isShare()){
            final CBase_EnterRoom req = new CBase_EnterRoom();
            req.setClubId(clubId);
            req.setRoomKey(roomId+"");
            req.setPassword("");
            req.setExistQuickJoin(false);
            req.setPosID(-1);
//            req.setGameNameStr();
//            req.setSignEnum();
                    ShareRoom shareRoom = ShareRoomMgr.getInstance().getShareRoomByKey(req.getRoomKey());
            if (shareRoom == null) {
                return false;
            }
            GameType gameType = GameTypeMgr.getInstance().gameType(shareRoom.getBaseRoomConfigure().getGameType().getId());
            long requestId = System.nanoTime();
            CommLogD.info("进入房间开始[{}],请求标识[{}]", gameType.getName(), requestId);
            if(GameListConfigMgr.getInstance().checkIsLiveByRoom(shareRoom)) {
                //检查游戏是否在维护中
                SData_Result result = MaintainGameMgr.getInstance().checkMaintainGame(gameType.getId(), player);
                if (!ErrorCode.Success.equals(result.getCode())) {
                    CommLogD.info(ErrorCode.Game_Maintain+MaintainGameMgr.getInstance().getMaintainGameContent(gameType.getId()));
                    return false;
                }
                GameTypeUrl gameTypeUrl = GameListConfigMgr.getInstance().getByRoom(shareRoom);
                ClubMember clubMember = ShareClubMemberMgr.getInstance().getClubMember(req.getClubId(), player.getPid());
                if (Objects.nonNull(clubMember)) {
                    if (clubMember.getClubMemberBO().getStatus() == Club_define.Club_Player_Status.PLAYER_TUICHU_WEIPIZHUN.value()) {
                        CommLogD.info(ErrorCode.NoPower_RoomJoinner+ "PLAYER_TUICHU_WEIPIZHUN");
                        return false;
                    }
                    SData_Result dataResult = ClubMgr.getInstance().getClubMemberMgr().checkSportsPointWarning(clubMember);
                    if(!ErrorCode.Success.equals(dataResult.getCode())){
                        CommLogD.info(ErrorCode.WarningSport_RoomJoinner+ dataResult.getMsg());
                        return false;
                    }
                    SData_Result dataResultPersonal=ClubMgr.getInstance().getClubMemberMgr().checkPersonalSportsPointWarning(clubMember);
                    if(!ErrorCode.Success.equals(dataResultPersonal.getCode())){
                        CommLogD.info(ErrorCode.PersonalWarningSport_RoomJoinner+ dataResultPersonal.getMsg());
                        return false;
                    }
                }
                ShareNode shareNode = new ShareNode("", gameTypeUrl.getWebSocketUrl(), gameTypeUrl.getGameServerIP(), gameTypeUrl.getGameServerPort());
                MqAbsRequestBo mqAbsRequestBo = new MqAbsRequestBo(player.getPid(), gameType.getName(), gameType.getId(), new Gson().toJson(req), "room.cbaseenterroom", shareNode);
                mqAbsRequestBo.setRequestId(requestId);
                mqAbsRequestBo.setShareNodeFrom(ShareNodeServerMgr.getInstance().getThisNode());
                //推送到MQ
                MqProducerMgr.get().send(MqTopic.BASE_ENTER_ROOM + gameType.getId(), mqAbsRequestBo);
                return true;
            } else {
                CommLogD.info(ErrorCode.Server_Maintain +String.valueOf(System.currentTimeMillis()/1000 + 300));
            }
        }
        return false;
    }

    private void addPlayers2ClubUnion(long num, Union union, int robotInitScore) {

        Club club = ClubMgr.getInstance().getClubListMgr().findClub(union.getUnionBO().getClubId());
        List<Player> players = PlayerMgr.getInstance().getAllClubRobotPlayers();
        for (Player player:players){
            if(num<=0){
                break;
            }
            if(player.getPlayerBO().getClubId()==0){
                CClub_Join req = CClub_Join.make(club.getClubListBO().getClubsign());
                SData_Result result = ClubMgr.getInstance().onJoinClub(player, req,true);
                if(ErrorCode.Success.equals(result.getCode())||ErrorCode.CLUB_EXIST_JIARU.equals(result.getCode())) {
                    num--;
                    player.getPlayerBO().saveClubId((int) union.getUnionBO().getClubId());
                    final CClub_SportsPointUpdate req2 = new CClub_SportsPointUpdate(club.getClubListBO().getId(),player.getPid(),0,robotInitScore);//上下分
                    result = ClubMgr.getInstance().getClubMemberMgr().execSportsPointUpdate(req2,club.getClubListBO().getOwnerID(),player);
                    System.out.println(result);
                }
            }
        }
    }

}
